class ListNode {
    val: number
    next: ListNode | null
    constructor(val?: number, next?: ListNode | null) {
        this.val = (val===undefined ? 0 : val)
        this.next = (next===undefined ? null : next)
    }
}


function removeZeroSumSublists(head: ListNode | null): ListNode | null {
    // 创建一个虚拟头节点，简化边界情况处理
    const dummy = new ListNode(0);
    dummy.next = head;
    
    // 使用哈希表存储前缀和及其对应的节点
    const prefixSumMap = new Map<number, ListNode>();
    let prefixSum = 0;
    let current: ListNode | null = dummy;
    
    // 第一次遍历：计算前缀和并建立映射
    while (current !== null) {
        prefixSum += current.val;
        // 如果遇到相同的前缀和，说明中间有和为0的连续序列
        // 更新映射，保留最后出现的位置
        prefixSumMap.set(prefixSum, current);
        current = current.next;
    }
    
    // 重置前缀和和当前指针
    prefixSum = 0;
    current = dummy;
    
    // 第二次遍历：删除和为0的连续序列
    while (current !== null) {
        prefixSum += current.val;
        
        // 如果当前前缀和在哈希表中存在，并且对应的节点不是当前节点
        // 说明从当前节点的下一个节点到映射节点之间的序列和为0
        if (prefixSumMap.has(prefixSum)) {
            const targetNode = prefixSumMap.get(prefixSum)!;
            // 只有当目标节点在当前节点之后时才进行删除
            if (targetNode !== current) {
                current.next = targetNode.next;
            }
        }
        
        current = current.next;
    }
    
    return dummy.next;
}

// 测试辅助函数：将数组转换为链表
function arrayToList(arr: number[]): ListNode | null {
    if (arr.length === 0) return null;
    const head = new ListNode(arr[0]);
    let current = head;
    for (let i = 1; i < arr.length; i++) {
        current.next = new ListNode(arr[i]);
        current = current.next;
    }
    return head;
}

// 测试辅助函数：将链表转换为数组
function listToArray(head: ListNode | null): number[] {
    const result: number[] = [];
    let current = head;
    while (current !== null) {
        result.push(current.val);
        current = current.next;
    }
    return result;
}

// 测试示例
const test1 = arrayToList([1, 2, -3, 3, 1]);
console.log(listToArray(removeZeroSumSublists(test1))); // [3, 1] 或 [1, 2, 1]

const test2 = arrayToList([1, 2, 3, -3, 4]);
console.log(listToArray(removeZeroSumSublists(test2))); // [1, 2, 4]

const test3 = arrayToList([1, 2, 3, -3, -2]);
console.log(listToArray(removeZeroSumSublists(test3))); // [1]